import logging
import re

from lxml import etree

from tzhhone_bsc.errors import TzhhoneBscErrors
from tzhhone_bsc.log import logger

import requests


class BscCoins:
    def __init__(self, rank, address, coins, url):
        self.rank = rank

        self.coins = float(coins.replace(",", ""))
        self.url = url
        self.address = address.replace("/token/", "")


# 币种信息类
class BscInfo:
    def __init__(self, name, total_supply, holders, transfers, contract, decimals, official_site, price):
        self.name = name
        self.total_supply = total_supply
        self.holders = holders
        self.transfers = transfers
        self.contract = contract
        self.decimals = decimals
        self.official_site = official_site
        self.price = price

    def json(self):
        return {"name": self.name, "total_supply": self.total_supply, "holders": self.holders,
                "transfers": self.transfers
            , "contract": self.contract, "decimals": self.decimals, "official_site": self.official_site,
                "price": self.price}


class Bsc:
    def __init__(self, user_agent, token, proxies, encoding="utf8"):
        try:
            self.user_agent = user_agent
            self.session = requests.session()
            self.req = requests
            self.headers = {
                "user-agent": self.user_agent
            }
            self.proxies = proxies
            self.token = token

            res = self.session.get("https://bscscan.com/token/" + self.token, proxies=self.proxies,
                                   headers=self.headers)
            search_obj = re.search(r"sid\s=\s'(\S+)'", res.text)
            self.cookies = res.cookies
            self.sid = None
            if search_obj:
                self.sid = search_obj.group(1)
            self.html = res
            self.html.encoding = encoding
        except TzhhoneBscErrors:
            logger.warning("网页解析出现错误")

    def get(self):
        return self.html

    def add(self, url):
        headers = {
            "user-agent": self.user_agent
        }
        proxies = {
            "http": "socks5://127.0.0.1:7890",
            'https': 'socks5://127.0.0.1:7890'
        }

        res = self.session.get(url, proxies=proxies,
                               headers=headers)
        self.html = res
        return self.html

    # 获取币种信息
    def get_info(self):
        try:
            if self.html is not None:
                html = etree.HTML(self.html.text)
                name = self.get_title()
                total_supply = html.xpath(
                    '//*[@id="ContentPlaceHolder1_divSummary"]/div[1]/div[1]/div/div[2]/div[2]/div[2]/span[1]/text()')[
                    0].replace(",", "")
                holders = self.get_address_count()
                res = self.req.get("https://bscscan.com/token/generic-tokentxns2?m=normal&contractAddress="
                                   + self.token + "&a=&sid=" + self.sid + "&p=1", cookies=self.cookies,
                                   headers=self.headers, proxies=self.proxies)

                search_obj = re.search(r"<\/i>[\s\S]+?([0-9]+,[0-9]+)[\s\S]+?<span", res.text)
                if search_obj:
                    transfers = search_obj.group(1).replace(",", "")
                else:
                    transfers = "-"
                contract = \
                    html.xpath('/html/body/div[1]/main/div[4]/div[1]/div[2]/div/div[2]/div[1]/div[2]/div/a[1]/text()')[
                        0]
                decimals = html.xpath('//*[@id="ContentPlaceHolder1_trDecimals"]/div/div[2]/text()')[0].replace("\n",
                                                                                                                "")
                official_site = html.xpath('//*[@id="ContentPlaceHolder1_tr_officialsite_1"]/div/div[2]/a/@href')[0]
                price = html.xpath('//*[@id="ContentPlaceHolder1_tr_valuepertoken"]/div/div[1]/span/span[1]/text()')[
                    0].replace("$", "")
                return BscInfo(name, total_supply, holders, transfers, contract, decimals, official_site, price)





            else:
                logger.warning("Errors:", "请先初始化")
        except TzhhoneBscErrors:
            logger.warning("Errors:网页解析出现错误")

    # 获取币种标题
    def get_title(self):
        try:
            if self.html is not None:

                html = etree.HTML(self.html.text)
                return html.xpath('//*[@id="content"]/div[1]/div/div[1]/h1/div/span/text()')[0]



            else:
                logger.warning("Errors:", "请先初始化")
        except TzhhoneBscErrors:
            logger.warning("Errors:网页解析出现错误")

    # 获取地址数量
    def get_address_count(self):
        try:
            if self.html is not None:
                html = etree.HTML(self.html.text)
                ret = html.xpath('//*[@id="ContentPlaceHolder1_tr_tokenHolders"]/div/div[2]/div/div/text()')[0]

                return int(ret.replace("addresses", "").replace(",", ""))
            else:
                logger.warning("Errors:", "请先初始化")
        except TzhhoneBscErrors:
            logger.warning("Errors:网页解析出现错误")

    # 获取持币地址详情
    def get_address_info(self, page=1):
        coins_html = self.session.get(
            "https://bscscan.com/token/generic-tokenholders2?m=normal&a=" + self.token + "&p=1",
            headers=self.headers, proxies=self.proxies)
        coins_html.encoding = self.html.encoding
        arr = []
        try:
            if coins_html is not None:

                html = etree.HTML(coins_html.text)
                rank = html.xpath('//*[@id="maintable"]/div[3]/table/tbody/tr/td[1]/text()')
                token = html.xpath('/html/body/div[2]/div[3]/table/tbody/tr/td[2]/span/a/text()')
                url = html.xpath('/html/body/div[2]/div[3]/table/tbody/tr/td[2]/span/a/@href')
                coins = html.xpath('//*[@id="maintable"]/div[3]/table/tbody/tr/td[3]/text()')
                ret_list = []

                if len(rank) is len(token) is len(coins) is len(url):
                    for item in range(len(rank)):
                        ret_list.append(BscCoins(rank[item], token[item], coins[item], url[item]))
                    return ret_list
                else:
                    return None
            else:
                logger.warning("Errors:", "请先初始化")
        except TzhhoneBscErrors:
            logger.warning("Errors:网页解析出现错误")
